/* -*-c-*- */
/* Copyright (C) 2003  Marcus Lundblad */
/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see: <http://www.gnu.org/licenses/>
 */

#include "config.h"

#include <stdio.h>
#include <X11/Xlib.h>
#include "fvwmlib.h"
#include "CombineChars.h"

/* ---------------------------- local types -------------------------------- */

typedef struct char_combclass
{
	unsigned short key;
	int combclass;
} char_combclass_t;


typedef struct char_comb
{
	unsigned short key;
	unsigned short first;
	unsigned short second;
} char_comb_t;

/* ---------------------------- static variables --------------------------- */

/* would like to use the Unicode replacement character here, but that would
   result in expanding incoming UTF-8 strings when garbage characters occurs */
/* so for the time being use '?' */
static unsigned short REPLACEMENT_CHARACTER = 0x3f;

/* maps characters to combination classes (not in list => 0) */
/* parsed from UnicodeData-3.2.0.txt */
static const char_combclass_t combclass_table[] =
{
	{ 0x0300, 230},
	{ 0x0301, 230},
	{ 0x0302, 230},
	{ 0x0303, 230},
	{ 0x0304, 230},
	{ 0x0305, 230},
	{ 0x0306, 230},
	{ 0x0307, 230},
	{ 0x0308, 230},
	{ 0x0309, 230},
	{ 0x030A, 230},
	{ 0x030B, 230},
	{ 0x030C, 230},
	{ 0x030D, 230},
	{ 0x030E, 230},
	{ 0x030F, 230},
	{ 0x0310, 230},
	{ 0x0311, 230},
	{ 0x0312, 230},
	{ 0x0313, 230},
	{ 0x0314, 230},
	{ 0x0315, 232},
	{ 0x0316, 220},
	{ 0x0317, 220},
	{ 0x0318, 220},
	{ 0x0319, 220},
	{ 0x031A, 232},
	{ 0x031B, 216},
	{ 0x031C, 220},
	{ 0x031D, 220},
	{ 0x031E, 220},
	{ 0x031F, 220},
	{ 0x0320, 220},
	{ 0x0321, 202},
	{ 0x0322, 202},
	{ 0x0323, 220},
	{ 0x0324, 220},
	{ 0x0325, 220},
	{ 0x0326, 220},
	{ 0x0327, 202},
	{ 0x0328, 202},
	{ 0x0329, 220},
	{ 0x032A, 220},
	{ 0x032B, 220},
	{ 0x032C, 220},
	{ 0x032D, 220},
	{ 0x032E, 220},
	{ 0x032F, 220},
	{ 0x0330, 220},
	{ 0x0331, 220},
	{ 0x0332, 220},
	{ 0x0333, 220},
	{ 0x0334, 1},
	{ 0x0335, 1},
	{ 0x0336, 1},
	{ 0x0337, 1},
	{ 0x0338, 1},
	{ 0x0339, 220},
	{ 0x033A, 220},
	{ 0x033B, 220},
	{ 0x033C, 220},
	{ 0x033D, 230},
	{ 0x033E, 230},
	{ 0x033F, 230},
	{ 0x0340, 230},
	{ 0x0341, 230},
	{ 0x0342, 230},
	{ 0x0343, 230},
	{ 0x0344, 230},
	{ 0x0345, 240},
	{ 0x0346, 230},
	{ 0x0347, 220},
	{ 0x0348, 220},
	{ 0x0349, 220},
	{ 0x034A, 230},
	{ 0x034B, 230},
	{ 0x034C, 230},
	{ 0x034D, 220},
	{ 0x034E, 220},
	{ 0x034F, -1 },
	{ 0x0360, 234},
	{ 0x0361, 234},
	{ 0x0362, 233},
	{ 0x0363, 230},
	{ 0x0364, 230},
	{ 0x0365, 230},
	{ 0x0366, 230},
	{ 0x0367, 230},
	{ 0x0368, 230},
	{ 0x0369, 230},
	{ 0x036A, 230},
	{ 0x036B, 230},
	{ 0x036C, 230},
	{ 0x036D, 230},
	{ 0x036E, 230},
	{ 0x036F, 230},
	{ 0x0483, 230},
	{ 0x0484, 230},
	{ 0x0485, 230},
	{ 0x0486, 230},
	{ 0x0488, -3 },
	{ 0x0489, -3 },
	{ 0x0591, 220},
	{ 0x0592, 230},
	{ 0x0593, 230},
	{ 0x0594, 230},
	{ 0x0595, 230},
	{ 0x0596, 220},
	{ 0x0597, 230},
	{ 0x0598, 230},
	{ 0x0599, 230},
	{ 0x059A, 222},
	{ 0x059B, 220},
	{ 0x059C, 230},
	{ 0x059D, 230},
	{ 0x059E, 230},
	{ 0x059F, 230},
	{ 0x05A0, 230},
	{ 0x05A1, 230},
	{ 0x05A3, 220},
	{ 0x05A4, 220},
	{ 0x05A5, 220},
	{ 0x05A6, 220},
	{ 0x05A7, 220},
	{ 0x05A8, 230},
	{ 0x05A9, 230},
	{ 0x05AA, 220},
	{ 0x05AB, 230},
	{ 0x05AC, 230},
	{ 0x05AD, 222},
	{ 0x05AE, 228},
	{ 0x05AF, 230},
	{ 0x05B0, 10},
	{ 0x05B1, 11},
	{ 0x05B2, 12},
	{ 0x05B3, 13},
	{ 0x05B4, 14},
	{ 0x05B5, 15},
	{ 0x05B6, 16},
	{ 0x05B7, 17},
	{ 0x05B8, 18},
	{ 0x05B9, 19},
	{ 0x05BB, 20},
	{ 0x05BC, 21},
	{ 0x05BD, 22},
	{ 0x05BF, 23},
	{ 0x05C1, 24},
	{ 0x05C2, 25},
	{ 0x05C4, 230},
	{ 0x064B, 27},
	{ 0x064C, 28},
	{ 0x064D, 29},
	{ 0x064E, 30},
	{ 0x064F, 31},
	{ 0x0650, 32},
	{ 0x0651, 33},
	{ 0x0652, 34},
	{ 0x0653, 230},
	{ 0x0654, 230},
	{ 0x0655, 220},
	{ 0x0670, 35},
	{ 0x06D6, 230},
	{ 0x06D7, 230},
	{ 0x06D8, 230},
	{ 0x06D9, 230},
	{ 0x06DA, 230},
	{ 0x06DB, 230},
	{ 0x06DC, 230},
	{ 0x06DE, -3 },
	{ 0x06DF, 230},
	{ 0x06E0, 230},
	{ 0x06E1, 230},
	{ 0x06E2, 230},
	{ 0x06E3, 220},
	{ 0x06E4, 230},
	{ 0x06E7, 230},
	{ 0x06E8, 230},
	{ 0x06EA, 220},
	{ 0x06EB, 230},
	{ 0x06EC, 230},
	{ 0x06ED, 220},
	{ 0x0711, 36},
	{ 0x0730, 230},
	{ 0x0731, 220},
	{ 0x0732, 230},
	{ 0x0733, 230},
	{ 0x0734, 220},
	{ 0x0735, 230},
	{ 0x0736, 230},
	{ 0x0737, 220},
	{ 0x0738, 220},
	{ 0x0739, 220},
	{ 0x073A, 230},
	{ 0x073B, 220},
	{ 0x073C, 220},
	{ 0x073D, 230},
	{ 0x073E, 220},
	{ 0x073F, 230},
	{ 0x0740, 230},
	{ 0x0741, 230},
	{ 0x0742, 220},
	{ 0x0743, 230},
	{ 0x0744, 220},
	{ 0x0745, 230},
	{ 0x0746, 220},
	{ 0x0747, 230},
	{ 0x0748, 220},
	{ 0x0749, 230},
	{ 0x074A, 230},
	{ 0x07A6, -1 },
	{ 0x07A7, -1 },
	{ 0x07A8, -1 },
	{ 0x07A9, -1 },
	{ 0x07AA, -1 },
	{ 0x07AB, -1 },
	{ 0x07AC, -1 },
	{ 0x07AD, -1 },
	{ 0x07AE, -1 },
	{ 0x07AF, -1 },
	{ 0x07B0, -1 },
	{ 0x0901, -1 },
	{ 0x0902, -1 },
	{ 0x0903, -2 },
	{ 0x093C, 7},
	{ 0x093E, -2 },
	{ 0x093F, -2 },
	{ 0x0940, -2 },
	{ 0x0941, -1 },
	{ 0x0942, -1 },
	{ 0x0943, -1 },
	{ 0x0944, -1 },
	{ 0x0945, -1 },
	{ 0x0946, -1 },
	{ 0x0947, -1 },
	{ 0x0948, -1 },
	{ 0x0949, -2 },
	{ 0x094A, -2 },
	{ 0x094B, -2 },
	{ 0x094C, -2 },
	{ 0x094D, 9},
	{ 0x0951, 230},
	{ 0x0952, 220},
	{ 0x0953, 230},
	{ 0x0954, 230},
	{ 0x0962, -1 },
	{ 0x0963, -1 },
	{ 0x0981, -1 },
	{ 0x0982, -2 },
	{ 0x0983, -2 },
	{ 0x09BC, 7},
	{ 0x09BE, -2 },
	{ 0x09BF, -2 },
	{ 0x09C0, -2 },
	{ 0x09C1, -1 },
	{ 0x09C2, -1 },
	{ 0x09C3, -1 },
	{ 0x09C4, -1 },
	{ 0x09C7, -2 },
	{ 0x09C8, -2 },
	{ 0x09CB, -2 },
	{ 0x09CC, -2 },
	{ 0x09CD, 9},
	{ 0x09D7, -2 },
	{ 0x09E2, -1 },
	{ 0x09E3, -1 },
	{ 0x0A02, -1 },
	{ 0x0A3C, 7},
	{ 0x0A3E, -2 },
	{ 0x0A3F, -2 },
	{ 0x0A40, -2 },
	{ 0x0A41, -1 },
	{ 0x0A42, -1 },
	{ 0x0A47, -1 },
	{ 0x0A48, -1 },
	{ 0x0A4B, -1 },
	{ 0x0A4C, -1 },
	{ 0x0A4D, 9},
	{ 0x0A70, -1 },
	{ 0x0A71, -1 },
	{ 0x0A81, -1 },
	{ 0x0A82, -1 },
	{ 0x0A83, -2 },
	{ 0x0ABC, 7},
	{ 0x0ABE, -2 },
	{ 0x0ABF, -2 },
	{ 0x0AC0, -2 },
	{ 0x0AC1, -1 },
	{ 0x0AC2, -1 },
	{ 0x0AC3, -1 },
	{ 0x0AC4, -1 },
	{ 0x0AC5, -1 },
	{ 0x0AC7, -1 },
	{ 0x0AC8, -1 },
	{ 0x0AC9, -2 },
	{ 0x0ACB, -2 },
	{ 0x0ACC, -2 },
	{ 0x0ACD, 9},
	{ 0x0B01, -1 },
	{ 0x0B02, -2 },
	{ 0x0B03, -2 },
	{ 0x0B3C, 7},
	{ 0x0B3E, -2 },
	{ 0x0B3F, -1 },
	{ 0x0B40, -2 },
	{ 0x0B41, -1 },
	{ 0x0B42, -1 },
	{ 0x0B43, -1 },
	{ 0x0B47, -2 },
	{ 0x0B48, -2 },
	{ 0x0B4B, -2 },
	{ 0x0B4C, -2 },
	{ 0x0B4D, 9},
	{ 0x0B56, -1 },
	{ 0x0B57, -2 },
	{ 0x0B82, -1 },
	{ 0x0BBE, -2 },
	{ 0x0BBF, -2 },
	{ 0x0BC0, -1 },
	{ 0x0BC1, -2 },
	{ 0x0BC2, -2 },
	{ 0x0BC6, -2 },
	{ 0x0BC7, -2 },
	{ 0x0BC8, -2 },
	{ 0x0BCA, -2 },
	{ 0x0BCB, -2 },
	{ 0x0BCC, -2 },
	{ 0x0BCD, 9},
	{ 0x0BD7, -2 },
	{ 0x0C01, -2 },
	{ 0x0C02, -2 },
	{ 0x0C03, -2 },
	{ 0x0C3E, -1 },
	{ 0x0C3F, -1 },
	{ 0x0C40, -1 },
	{ 0x0C41, -2 },
	{ 0x0C42, -2 },
	{ 0x0C43, -2 },
	{ 0x0C44, -2 },
	{ 0x0C46, -1 },
	{ 0x0C47, -1 },
	{ 0x0C48, -1 },
	{ 0x0C4A, -1 },
	{ 0x0C4B, -1 },
	{ 0x0C4C, -1 },
	{ 0x0C4D, 9},
	{ 0x0C55, 84},
	{ 0x0C56, 91},
	{ 0x0C82, -2 },
	{ 0x0C83, -2 },
	{ 0x0CBE, -2 },
	{ 0x0CBF, -1 },
	{ 0x0CC0, -2 },
	{ 0x0CC1, -2 },
	{ 0x0CC2, -2 },
	{ 0x0CC3, -2 },
	{ 0x0CC4, -2 },
	{ 0x0CC6, -1 },
	{ 0x0CC7, -2 },
	{ 0x0CC8, -2 },
	{ 0x0CCA, -2 },
	{ 0x0CCB, -2 },
	{ 0x0CCC, -1 },
	{ 0x0CCD, 9},
	{ 0x0CD5, -2 },
	{ 0x0CD6, -2 },
	{ 0x0D02, -2 },
	{ 0x0D03, -2 },
	{ 0x0D3E, -2 },
	{ 0x0D3F, -2 },
	{ 0x0D40, -2 },
	{ 0x0D41, -1 },
	{ 0x0D42, -1 },
	{ 0x0D43, -1 },
	{ 0x0D46, -2 },
	{ 0x0D47, -2 },
	{ 0x0D48, -2 },
	{ 0x0D4A, -2 },
	{ 0x0D4B, -2 },
	{ 0x0D4C, -2 },
	{ 0x0D4D, 9},
	{ 0x0D57, -2 },
	{ 0x0D82, -2 },
	{ 0x0D83, -2 },
	{ 0x0DCA, 9},
	{ 0x0DCF, -2 },
	{ 0x0DD0, -2 },
	{ 0x0DD1, -2 },
	{ 0x0DD2, -1 },
	{ 0x0DD3, -1 },
	{ 0x0DD4, -1 },
	{ 0x0DD6, -1 },
	{ 0x0DD8, -2 },
	{ 0x0DD9, -2 },
	{ 0x0DDA, -2 },
	{ 0x0DDB, -2 },
	{ 0x0DDC, -2 },
	{ 0x0DDD, -2 },
	{ 0x0DDE, -2 },
	{ 0x0DDF, -2 },
	{ 0x0DF2, -2 },
	{ 0x0DF3, -2 },
	{ 0x0E31, -1 },
	{ 0x0E34, -1 },
	{ 0x0E35, -1 },
	{ 0x0E36, -1 },
	{ 0x0E37, -1 },
	{ 0x0E38, 103},
	{ 0x0E39, 103},
	{ 0x0E3A, 9},
	{ 0x0E47, -1 },
	{ 0x0E48, 107},
	{ 0x0E49, 107},
	{ 0x0E4A, 107},
	{ 0x0E4B, 107},
	{ 0x0E4C, -1 },
	{ 0x0E4D, -1 },
	{ 0x0E4E, -1 },
	{ 0x0EB1, -1 },
	{ 0x0EB4, -1 },
	{ 0x0EB5, -1 },
	{ 0x0EB6, -1 },
	{ 0x0EB7, -1 },
	{ 0x0EB8, 118},
	{ 0x0EB9, 118},
	{ 0x0EBB, -1 },
	{ 0x0EBC, -1 },
	{ 0x0EC8, 122},
	{ 0x0EC9, 122},
	{ 0x0ECA, 122},
	{ 0x0ECB, 122},
	{ 0x0ECC, -1 },
	{ 0x0ECD, -1 },
	{ 0x0F18, 220},
	{ 0x0F19, 220},
	{ 0x0F35, 220},
	{ 0x0F37, 220},
	{ 0x0F39, 216},
	{ 0x0F3E, -2 },
	{ 0x0F3F, -2 },
	{ 0x0F71, 129},
	{ 0x0F72, 130},
	{ 0x0F73, -1 },
	{ 0x0F74, 132},
	{ 0x0F75, -1 },
	{ 0x0F76, -1 },
	{ 0x0F77, -1 },
	{ 0x0F78, -1 },
	{ 0x0F79, -1 },
	{ 0x0F7A, 130},
	{ 0x0F7B, 130},
	{ 0x0F7C, 130},
	{ 0x0F7D, 130},
	{ 0x0F7E, -1 },
	{ 0x0F7F, -2 },
	{ 0x0F80, 130},
	{ 0x0F81, -1 },
	{ 0x0F82, 230},
	{ 0x0F83, 230},
	{ 0x0F84, 9},
	{ 0x0F86, 230},
	{ 0x0F87, 230},
	{ 0x0F90, -1 },
	{ 0x0F91, -1 },
	{ 0x0F92, -1 },
	{ 0x0F93, -1 },
	{ 0x0F94, -1 },
	{ 0x0F95, -1 },
	{ 0x0F96, -1 },
	{ 0x0F97, -1 },
	{ 0x0F99, -1 },
	{ 0x0F9A, -1 },
	{ 0x0F9B, -1 },
	{ 0x0F9C, -1 },
	{ 0x0F9D, -1 },
	{ 0x0F9E, -1 },
	{ 0x0F9F, -1 },
	{ 0x0FA0, -1 },
	{ 0x0FA1, -1 },
	{ 0x0FA2, -1 },
	{ 0x0FA3, -1 },
	{ 0x0FA4, -1 },
	{ 0x0FA5, -1 },
	{ 0x0FA6, -1 },
	{ 0x0FA7, -1 },
	{ 0x0FA8, -1 },
	{ 0x0FA9, -1 },
	{ 0x0FAA, -1 },
	{ 0x0FAB, -1 },
	{ 0x0FAC, -1 },
	{ 0x0FAD, -1 },
	{ 0x0FAE, -1 },
	{ 0x0FAF, -1 },
	{ 0x0FB0, -1 },
	{ 0x0FB1, -1 },
	{ 0x0FB2, -1 },
	{ 0x0FB3, -1 },
	{ 0x0FB4, -1 },
	{ 0x0FB5, -1 },
	{ 0x0FB6, -1 },
	{ 0x0FB7, -1 },
	{ 0x0FB8, -1 },
	{ 0x0FB9, -1 },
	{ 0x0FBA, -1 },
	{ 0x0FBB, -1 },
	{ 0x0FBC, -1 },
	{ 0x0FC6, 220},
	{ 0x102C, -2 },
	{ 0x102D, -1 },
	{ 0x102E, -1 },
	{ 0x102F, -1 },
	{ 0x1030, -1 },
	{ 0x1031, -2 },
	{ 0x1032, -1 },
	{ 0x1036, -1 },
	{ 0x1037, 7},
	{ 0x1038, -2 },
	{ 0x1039, 9},
	{ 0x1056, -2 },
	{ 0x1057, -2 },
	{ 0x1058, -1 },
	{ 0x1059, -1 },
	{ 0x1712, -1 },
	{ 0x1713, -1 },
	{ 0x1714, 9},
	{ 0x1732, -1 },
	{ 0x1733, -1 },
	{ 0x1734, 9},
	{ 0x1752, -1 },
	{ 0x1753, -1 },
	{ 0x1772, -1 },
	{ 0x1773, -1 },
	{ 0x17B4, -2 },
	{ 0x17B5, -2 },
	{ 0x17B6, -2 },
	{ 0x17B7, -1 },
	{ 0x17B8, -1 },
	{ 0x17B9, -1 },
	{ 0x17BA, -1 },
	{ 0x17BB, -1 },
	{ 0x17BC, -1 },
	{ 0x17BD, -1 },
	{ 0x17BE, -2 },
	{ 0x17BF, -2 },
	{ 0x17C0, -2 },
	{ 0x17C1, -2 },
	{ 0x17C2, -2 },
	{ 0x17C3, -2 },
	{ 0x17C4, -2 },
	{ 0x17C5, -2 },
	{ 0x17C6, -1 },
	{ 0x17C7, -2 },
	{ 0x17C8, -2 },
	{ 0x17C9, -1 },
	{ 0x17CA, -1 },
	{ 0x17CB, -1 },
	{ 0x17CC, -1 },
	{ 0x17CD, -1 },
	{ 0x17CE, -1 },
	{ 0x17CF, -1 },
	{ 0x17D0, -1 },
	{ 0x17D1, -1 },
	{ 0x17D2, 9},
	{ 0x17D3, -1 },
	{ 0x180B, -1 },
	{ 0x180C, -1 },
	{ 0x180D, -1 },
	{ 0x18A9, 228},
	{ 0x20D0, 230},
	{ 0x20D1, 230},
	{ 0x20D2, 1},
	{ 0x20D3, 1},
	{ 0x20D4, 230},
	{ 0x20D5, 230},
	{ 0x20D6, 230},
	{ 0x20D7, 230},
	{ 0x20D8, 1},
	{ 0x20D9, 1},
	{ 0x20DA, 1},
	{ 0x20DB, 230},
	{ 0x20DC, 230},
	{ 0x20DD, -3 },
	{ 0x20DE, -3 },
	{ 0x20DF, -3 },
	{ 0x20E0, -3 },
	{ 0x20E1, 230},
	{ 0x20E2, -3 },
	{ 0x20E3, -3 },
	{ 0x20E4, -3 },
	{ 0x20E5, 1},
	{ 0x20E6, 1},
	{ 0x20E7, 230},
	{ 0x20E8, 220},
	{ 0x20E9, 230},
	{ 0x20EA, 1},
	{ 0x302A, 218},
	{ 0x302B, 228},
	{ 0x302C, 232},
	{ 0x302D, 222},
	{ 0x302E, 224},
	{ 0x302F, 224},
	{ 0x3099, 8},
	{ 0x309A, 8},
	{ 0xFB1E, 26},
	{ 0xFE00, -1 },
	{ 0xFE01, -1 },
	{ 0xFE02, -1 },
	{ 0xFE03, -1 },
	{ 0xFE04, -1 },
	{ 0xFE05, -1 },
	{ 0xFE06, -1 },
	{ 0xFE07, -1 },
	{ 0xFE08, -1 },
	{ 0xFE09, -1 },
	{ 0xFE0A, -1 },
	{ 0xFE0B, -1 },
	{ 0xFE0C, -1 },
	{ 0xFE0D, -1 },
	{ 0xFE0E, -1 },
	{ 0xFE0F, -1 },
	{ 0xFE20, 230},
	{ 0xFE21, 230},
	{ 0xFE22, 230},
	{ 0xFE23, 230},
	/*{ 0x1D165, 216},
	{ 0x1D166, 216},
	{ 0x1D167, 1},
	{ 0x1D168, 1},
	{ 0x1D169, 1},
	{ 0x1D16D, 226},
	{ 0x1D16E, 216},
	{ 0x1D16F, 216},
	{ 0x1D170, 216},
	{ 0x1D171, 216},
	{ 0x1D172, 216},
	{ 0x1D17B, 220},
	{ 0x1D17C, 220},
	{ 0x1D17D, 220},
	{ 0x1D17E, 220},
	{ 0x1D17F, 220},
	{ 0x1D180, 220},
	{ 0x1D181, 220},
	{ 0x1D182, 220},
	{ 0x1D185, 230},
	{ 0x1D186, 230},
	{ 0x1D187, 230},
	{ 0x1D188, 230},
	{ 0x1D189, 230},
	{ 0x1D18A, 220},
	{ 0x1D18B, 220},
	{ 0x1D1AA, 230},
	{ 0x1D1AB, 230},
	{ 0x1D1AC, 230},
	{ 0x1D1AD, 230},*/
};

/* maps characters to decompositions */
/* parsed from UnicodeData-3.2.0.txt */
static const char_comb_t comb_table[] =
{
	{ 0x00C0, 0x0041, 0x0300 },
	{ 0x00C1, 0x0041, 0x0301 },
	{ 0x00C2, 0x0041, 0x0302 },
	{ 0x00C3, 0x0041, 0x0303 },
	{ 0x00C4, 0x0041, 0x0308 },
	{ 0x00C5, 0x0041, 0x030A },
	{ 0x00C7, 0x0043, 0x0327 },
	{ 0x00C8, 0x0045, 0x0300 },
	{ 0x00C9, 0x0045, 0x0301 },
	{ 0x00CA, 0x0045, 0x0302 },
	{ 0x00CB, 0x0045, 0x0308 },
	{ 0x00CC, 0x0049, 0x0300 },
	{ 0x00CD, 0x0049, 0x0301 },
	{ 0x00CE, 0x0049, 0x0302 },
	{ 0x00CF, 0x0049, 0x0308 },
	{ 0x00D1, 0x004E, 0x0303 },
	{ 0x00D2, 0x004F, 0x0300 },
	{ 0x00D3, 0x004F, 0x0301 },
	{ 0x00D4, 0x004F, 0x0302 },
	{ 0x00D5, 0x004F, 0x0303 },
	{ 0x00D6, 0x004F, 0x0308 },
	{ 0x00D9, 0x0055, 0x0300 },
	{ 0x00DA, 0x0055, 0x0301 },
	{ 0x00DB, 0x0055, 0x0302 },
	{ 0x00DC, 0x0055, 0x0308 },
	{ 0x00DD, 0x0059, 0x0301 },
	{ 0x00E0, 0x0061, 0x0300 },
	{ 0x00E1, 0x0061, 0x0301 },
	{ 0x00E2, 0x0061, 0x0302 },
	{ 0x00E3, 0x0061, 0x0303 },
	{ 0x00E4, 0x0061, 0x0308 },
	{ 0x00E5, 0x0061, 0x030A },
	{ 0x00E7, 0x0063, 0x0327 },
	{ 0x00E8, 0x0065, 0x0300 },
	{ 0x00E9, 0x0065, 0x0301 },
	{ 0x00EA, 0x0065, 0x0302 },
	{ 0x00EB, 0x0065, 0x0308 },
	{ 0x00EC, 0x0069, 0x0300 },
	{ 0x00ED, 0x0069, 0x0301 },
	{ 0x00EE, 0x0069, 0x0302 },
	{ 0x00EF, 0x0069, 0x0308 },
	{ 0x00F1, 0x006E, 0x0303 },
	{ 0x00F2, 0x006F, 0x0300 },
	{ 0x00F3, 0x006F, 0x0301 },
	{ 0x00F4, 0x006F, 0x0302 },
	{ 0x00F5, 0x006F, 0x0303 },
	{ 0x00F6, 0x006F, 0x0308 },
	{ 0x00F9, 0x0075, 0x0300 },
	{ 0x00FA, 0x0075, 0x0301 },
	{ 0x00FB, 0x0075, 0x0302 },
	{ 0x00FC, 0x0075, 0x0308 },
	{ 0x00FD, 0x0079, 0x0301 },
	{ 0x00FF, 0x0079, 0x0308 },
	{ 0x0100, 0x0041, 0x0304 },
	{ 0x0101, 0x0061, 0x0304 },
	{ 0x0102, 0x0041, 0x0306 },
	{ 0x0103, 0x0061, 0x0306 },
	{ 0x0104, 0x0041, 0x0328 },
	{ 0x0105, 0x0061, 0x0328 },
	{ 0x0106, 0x0043, 0x0301 },
	{ 0x0107, 0x0063, 0x0301 },
	{ 0x0108, 0x0043, 0x0302 },
	{ 0x0109, 0x0063, 0x0302 },
	{ 0x010A, 0x0043, 0x0307 },
	{ 0x010B, 0x0063, 0x0307 },
	{ 0x010C, 0x0043, 0x030C },
	{ 0x010D, 0x0063, 0x030C },
	{ 0x010E, 0x0044, 0x030C },
	{ 0x010F, 0x0064, 0x030C },
	{ 0x0112, 0x0045, 0x0304 },
	{ 0x0113, 0x0065, 0x0304 },
	{ 0x0114, 0x0045, 0x0306 },
	{ 0x0115, 0x0065, 0x0306 },
	{ 0x0116, 0x0045, 0x0307 },
	{ 0x0117, 0x0065, 0x0307 },
	{ 0x0118, 0x0045, 0x0328 },
	{ 0x0119, 0x0065, 0x0328 },
	{ 0x011A, 0x0045, 0x030C },
	{ 0x011B, 0x0065, 0x030C },
	{ 0x011C, 0x0047, 0x0302 },
	{ 0x011D, 0x0067, 0x0302 },
	{ 0x011E, 0x0047, 0x0306 },
	{ 0x011F, 0x0067, 0x0306 },
	{ 0x0120, 0x0047, 0x0307 },
	{ 0x0121, 0x0067, 0x0307 },
	{ 0x0122, 0x0047, 0x0327 },
	{ 0x0123, 0x0067, 0x0327 },
	{ 0x0124, 0x0048, 0x0302 },
	{ 0x0125, 0x0068, 0x0302 },
	{ 0x0128, 0x0049, 0x0303 },
	{ 0x0129, 0x0069, 0x0303 },
	{ 0x012A, 0x0049, 0x0304 },
	{ 0x012B, 0x0069, 0x0304 },
	{ 0x012C, 0x0049, 0x0306 },
	{ 0x012D, 0x0069, 0x0306 },
	{ 0x012E, 0x0049, 0x0328 },
	{ 0x012F, 0x0069, 0x0328 },
	{ 0x0130, 0x0049, 0x0307 },
	{ 0x0134, 0x004A, 0x0302 },
	{ 0x0135, 0x006A, 0x0302 },
	{ 0x0136, 0x004B, 0x0327 },
	{ 0x0137, 0x006B, 0x0327 },
	{ 0x0139, 0x004C, 0x0301 },
	{ 0x013A, 0x006C, 0x0301 },
	{ 0x013B, 0x004C, 0x0327 },
	{ 0x013C, 0x006C, 0x0327 },
	{ 0x013D, 0x004C, 0x030C },
	{ 0x013E, 0x006C, 0x030C },
	{ 0x0143, 0x004E, 0x0301 },
	{ 0x0144, 0x006E, 0x0301 },
	{ 0x0145, 0x004E, 0x0327 },
	{ 0x0146, 0x006E, 0x0327 },
	{ 0x0147, 0x004E, 0x030C },
	{ 0x0148, 0x006E, 0x030C },
	{ 0x014C, 0x004F, 0x0304 },
	{ 0x014D, 0x006F, 0x0304 },
	{ 0x014E, 0x004F, 0x0306 },
	{ 0x014F, 0x006F, 0x0306 },
	{ 0x0150, 0x004F, 0x030B },
	{ 0x0151, 0x006F, 0x030B },
	{ 0x0154, 0x0052, 0x0301 },
	{ 0x0155, 0x0072, 0x0301 },
	{ 0x0156, 0x0052, 0x0327 },
	{ 0x0157, 0x0072, 0x0327 },
	{ 0x0158, 0x0052, 0x030C },
	{ 0x0159, 0x0072, 0x030C },
	{ 0x015A, 0x0053, 0x0301 },
	{ 0x015B, 0x0073, 0x0301 },
	{ 0x015C, 0x0053, 0x0302 },
	{ 0x015D, 0x0073, 0x0302 },
	{ 0x015E, 0x0053, 0x0327 },
	{ 0x015F, 0x0073, 0x0327 },
	{ 0x0160, 0x0053, 0x030C },
	{ 0x0161, 0x0073, 0x030C },
	{ 0x0162, 0x0054, 0x0327 },
	{ 0x0163, 0x0074, 0x0327 },
	{ 0x0164, 0x0054, 0x030C },
	{ 0x0165, 0x0074, 0x030C },
	{ 0x0168, 0x0055, 0x0303 },
	{ 0x0169, 0x0075, 0x0303 },
	{ 0x016A, 0x0055, 0x0304 },
	{ 0x016B, 0x0075, 0x0304 },
	{ 0x016C, 0x0055, 0x0306 },
	{ 0x016D, 0x0075, 0x0306 },
	{ 0x016E, 0x0055, 0x030A },
	{ 0x016F, 0x0075, 0x030A },
	{ 0x0170, 0x0055, 0x030B },
	{ 0x0171, 0x0075, 0x030B },
	{ 0x0172, 0x0055, 0x0328 },
	{ 0x0173, 0x0075, 0x0328 },
	{ 0x0174, 0x0057, 0x0302 },
	{ 0x0175, 0x0077, 0x0302 },
	{ 0x0176, 0x0059, 0x0302 },
	{ 0x0177, 0x0079, 0x0302 },
	{ 0x0178, 0x0059, 0x0308 },
	{ 0x0179, 0x005A, 0x0301 },
	{ 0x017A, 0x007A, 0x0301 },
	{ 0x017B, 0x005A, 0x0307 },
	{ 0x017C, 0x007A, 0x0307 },
	{ 0x017D, 0x005A, 0x030C },
	{ 0x017E, 0x007A, 0x030C },
	{ 0x01A0, 0x004F, 0x031B },
	{ 0x01A1, 0x006F, 0x031B },
	{ 0x01AF, 0x0055, 0x031B },
	{ 0x01B0, 0x0075, 0x031B },
	{ 0x01CD, 0x0041, 0x030C },
	{ 0x01CE, 0x0061, 0x030C },
	{ 0x01CF, 0x0049, 0x030C },
	{ 0x01D0, 0x0069, 0x030C },
	{ 0x01D1, 0x004F, 0x030C },
	{ 0x01D2, 0x006F, 0x030C },
	{ 0x01D3, 0x0055, 0x030C },
	{ 0x01D4, 0x0075, 0x030C },
	{ 0x01D5, 0x00DC, 0x0304 },
	{ 0x01D6, 0x00FC, 0x0304 },
	{ 0x01D7, 0x00DC, 0x0301 },
	{ 0x01D8, 0x00FC, 0x0301 },
	{ 0x01D9, 0x00DC, 0x030C },
	{ 0x01DA, 0x00FC, 0x030C },
	{ 0x01DB, 0x00DC, 0x0300 },
	{ 0x01DC, 0x00FC, 0x0300 },
	{ 0x01DE, 0x00C4, 0x0304 },
	{ 0x01DF, 0x00E4, 0x0304 },
	{ 0x01E0, 0x0226, 0x0304 },
	{ 0x01E1, 0x0227, 0x0304 },
	{ 0x01E2, 0x00C6, 0x0304 },
	{ 0x01E3, 0x00E6, 0x0304 },
	{ 0x01E6, 0x0047, 0x030C },
	{ 0x01E7, 0x0067, 0x030C },
	{ 0x01E8, 0x004B, 0x030C },
	{ 0x01E9, 0x006B, 0x030C },
	{ 0x01EA, 0x004F, 0x0328 },
	{ 0x01EB, 0x006F, 0x0328 },
	{ 0x01EC, 0x01EA, 0x0304 },
	{ 0x01ED, 0x01EB, 0x0304 },
	{ 0x01EE, 0x01B7, 0x030C },
	{ 0x01EF, 0x0292, 0x030C },
	{ 0x01F0, 0x006A, 0x030C },
	{ 0x01F4, 0x0047, 0x0301 },
	{ 0x01F5, 0x0067, 0x0301 },
	{ 0x01F8, 0x004E, 0x0300 },
	{ 0x01F9, 0x006E, 0x0300 },
	{ 0x01FA, 0x00C5, 0x0301 },
	{ 0x01FB, 0x00E5, 0x0301 },
	{ 0x01FC, 0x00C6, 0x0301 },
	{ 0x01FD, 0x00E6, 0x0301 },
	{ 0x01FE, 0x00D8, 0x0301 },
	{ 0x01FF, 0x00F8, 0x0301 },
	{ 0x0200, 0x0041, 0x030F },
	{ 0x0201, 0x0061, 0x030F },
	{ 0x0202, 0x0041, 0x0311 },
	{ 0x0203, 0x0061, 0x0311 },
	{ 0x0204, 0x0045, 0x030F },
	{ 0x0205, 0x0065, 0x030F },
	{ 0x0206, 0x0045, 0x0311 },
	{ 0x0207, 0x0065, 0x0311 },
	{ 0x0208, 0x0049, 0x030F },
	{ 0x0209, 0x0069, 0x030F },
	{ 0x020A, 0x0049, 0x0311 },
	{ 0x020B, 0x0069, 0x0311 },
	{ 0x020C, 0x004F, 0x030F },
	{ 0x020D, 0x006F, 0x030F },
	{ 0x020E, 0x004F, 0x0311 },
	{ 0x020F, 0x006F, 0x0311 },
	{ 0x0210, 0x0052, 0x030F },
	{ 0x0211, 0x0072, 0x030F },
	{ 0x0212, 0x0052, 0x0311 },
	{ 0x0213, 0x0072, 0x0311 },
	{ 0x0214, 0x0055, 0x030F },
	{ 0x0215, 0x0075, 0x030F },
	{ 0x0216, 0x0055, 0x0311 },
	{ 0x0217, 0x0075, 0x0311 },
	{ 0x0218, 0x0053, 0x0326 },
	{ 0x0219, 0x0073, 0x0326 },
	{ 0x021A, 0x0054, 0x0326 },
	{ 0x021B, 0x0074, 0x0326 },
	{ 0x021E, 0x0048, 0x030C },
	{ 0x021F, 0x0068, 0x030C },
	{ 0x0226, 0x0041, 0x0307 },
	{ 0x0227, 0x0061, 0x0307 },
	{ 0x0228, 0x0045, 0x0327 },
	{ 0x0229, 0x0065, 0x0327 },
	{ 0x022A, 0x00D6, 0x0304 },
	{ 0x022B, 0x00F6, 0x0304 },
	{ 0x022C, 0x00D5, 0x0304 },
	{ 0x022D, 0x00F5, 0x0304 },
	{ 0x022E, 0x004F, 0x0307 },
	{ 0x022F, 0x006F, 0x0307 },
	{ 0x0230, 0x022E, 0x0304 },
	{ 0x0231, 0x022F, 0x0304 },
	{ 0x0232, 0x0059, 0x0304 },
	{ 0x0233, 0x0079, 0x0304 },
	{ 0x0344, 0x0308, 0x0301 },
	{ 0x0385, 0x00A8, 0x0301 },
	{ 0x0386, 0x0391, 0x0301 },
	{ 0x0388, 0x0395, 0x0301 },
	{ 0x0389, 0x0397, 0x0301 },
	{ 0x038A, 0x0399, 0x0301 },
	{ 0x038C, 0x039F, 0x0301 },
	{ 0x038E, 0x03A5, 0x0301 },
	{ 0x038F, 0x03A9, 0x0301 },
	{ 0x0390, 0x03CA, 0x0301 },
	{ 0x03AA, 0x0399, 0x0308 },
	{ 0x03AB, 0x03A5, 0x0308 },
	{ 0x03AC, 0x03B1, 0x0301 },
	{ 0x03AD, 0x03B5, 0x0301 },
	{ 0x03AE, 0x03B7, 0x0301 },
	{ 0x03AF, 0x03B9, 0x0301 },
	{ 0x03B0, 0x03CB, 0x0301 },
	{ 0x03CA, 0x03B9, 0x0308 },
	{ 0x03CB, 0x03C5, 0x0308 },
	{ 0x03CC, 0x03BF, 0x0301 },
	{ 0x03CD, 0x03C5, 0x0301 },
	{ 0x03CE, 0x03C9, 0x0301 },
	{ 0x03D3, 0x03D2, 0x0301 },
	{ 0x03D4, 0x03D2, 0x0308 },
	{ 0x0400, 0x0415, 0x0300 },
	{ 0x0401, 0x0415, 0x0308 },
	{ 0x0403, 0x0413, 0x0301 },
	{ 0x0407, 0x0406, 0x0308 },
	{ 0x040C, 0x041A, 0x0301 },
	{ 0x040D, 0x0418, 0x0300 },
	{ 0x040E, 0x0423, 0x0306 },
	{ 0x0419, 0x0418, 0x0306 },
	{ 0x0439, 0x0438, 0x0306 },
	{ 0x0450, 0x0435, 0x0300 },
	{ 0x0451, 0x0435, 0x0308 },
	{ 0x0453, 0x0433, 0x0301 },
	{ 0x0457, 0x0456, 0x0308 },
	{ 0x045C, 0x043A, 0x0301 },
	{ 0x045D, 0x0438, 0x0300 },
	{ 0x045E, 0x0443, 0x0306 },
	{ 0x0476, 0x0474, 0x030F },
	{ 0x0477, 0x0475, 0x030F },
	{ 0x04C1, 0x0416, 0x0306 },
	{ 0x04C2, 0x0436, 0x0306 },
	{ 0x04D0, 0x0410, 0x0306 },
	{ 0x04D1, 0x0430, 0x0306 },
	{ 0x04D2, 0x0410, 0x0308 },
	{ 0x04D3, 0x0430, 0x0308 },
	{ 0x04D6, 0x0415, 0x0306 },
	{ 0x04D7, 0x0435, 0x0306 },
	{ 0x04DA, 0x04D8, 0x0308 },
	{ 0x04DB, 0x04D9, 0x0308 },
	{ 0x04DC, 0x0416, 0x0308 },
	{ 0x04DD, 0x0436, 0x0308 },
	{ 0x04DE, 0x0417, 0x0308 },
	{ 0x04DF, 0x0437, 0x0308 },
	{ 0x04E2, 0x0418, 0x0304 },
	{ 0x04E3, 0x0438, 0x0304 },
	{ 0x04E4, 0x0418, 0x0308 },
	{ 0x04E5, 0x0438, 0x0308 },
	{ 0x04E6, 0x041E, 0x0308 },
	{ 0x04E7, 0x043E, 0x0308 },
	{ 0x04EA, 0x04E8, 0x0308 },
	{ 0x04EB, 0x04E9, 0x0308 },
	{ 0x04EC, 0x042D, 0x0308 },
	{ 0x04ED, 0x044D, 0x0308 },
	{ 0x04EE, 0x0423, 0x0304 },
	{ 0x04EF, 0x0443, 0x0304 },
	{ 0x04F0, 0x0423, 0x0308 },
	{ 0x04F1, 0x0443, 0x0308 },
	{ 0x04F2, 0x0423, 0x030B },
	{ 0x04F3, 0x0443, 0x030B },
	{ 0x04F4, 0x0427, 0x0308 },
	{ 0x04F5, 0x0447, 0x0308 },
	{ 0x04F8, 0x042B, 0x0308 },
	{ 0x04F9, 0x044B, 0x0308 },
	{ 0x0622, 0x0627, 0x0653 },
	{ 0x0623, 0x0627, 0x0654 },
	{ 0x0624, 0x0648, 0x0654 },
	{ 0x0625, 0x0627, 0x0655 },
	{ 0x0626, 0x064A, 0x0654 },
	{ 0x06C0, 0x06D5, 0x0654 },
	{ 0x06C2, 0x06C1, 0x0654 },
	{ 0x06D3, 0x06D2, 0x0654 },
	{ 0x0929, 0x0928, 0x093C },
	{ 0x0931, 0x0930, 0x093C },
	{ 0x0934, 0x0933, 0x093C },
	{ 0x0958, 0x0915, 0x093C },
	{ 0x0959, 0x0916, 0x093C },
	{ 0x095A, 0x0917, 0x093C },
	{ 0x095B, 0x091C, 0x093C },
	{ 0x095C, 0x0921, 0x093C },
	{ 0x095D, 0x0922, 0x093C },
	{ 0x095E, 0x092B, 0x093C },
	{ 0x095F, 0x092F, 0x093C },
	{ 0x09CB, 0x09C7, 0x09BE },
	{ 0x09CC, 0x09C7, 0x09D7 },
	{ 0x09DC, 0x09A1, 0x09BC },
	{ 0x09DD, 0x09A2, 0x09BC },
	{ 0x09DF, 0x09AF, 0x09BC },
	{ 0x0A33, 0x0A32, 0x0A3C },
	{ 0x0A36, 0x0A38, 0x0A3C },
	{ 0x0A59, 0x0A16, 0x0A3C },
	{ 0x0A5A, 0x0A17, 0x0A3C },
	{ 0x0A5B, 0x0A1C, 0x0A3C },
	{ 0x0A5E, 0x0A2B, 0x0A3C },
	{ 0x0B48, 0x0B47, 0x0B56 },
	{ 0x0B4B, 0x0B47, 0x0B3E },
	{ 0x0B4C, 0x0B47, 0x0B57 },
	{ 0x0B5C, 0x0B21, 0x0B3C },
	{ 0x0B5D, 0x0B22, 0x0B3C },
	{ 0x0B94, 0x0B92, 0x0BD7 },
	{ 0x0BCA, 0x0BC6, 0x0BBE },
	{ 0x0BCB, 0x0BC7, 0x0BBE },
	{ 0x0BCC, 0x0BC6, 0x0BD7 },
	{ 0x0C48, 0x0C46, 0x0C56 },
	{ 0x0CC0, 0x0CBF, 0x0CD5 },
	{ 0x0CC7, 0x0CC6, 0x0CD5 },
	{ 0x0CC8, 0x0CC6, 0x0CD6 },
	{ 0x0CCA, 0x0CC6, 0x0CC2 },
	{ 0x0CCB, 0x0CCA, 0x0CD5 },
	{ 0x0D4A, 0x0D46, 0x0D3E },
	{ 0x0D4B, 0x0D47, 0x0D3E },
	{ 0x0D4C, 0x0D46, 0x0D57 },
	{ 0x0DDA, 0x0DD9, 0x0DCA },
	{ 0x0DDC, 0x0DD9, 0x0DCF },
	{ 0x0DDD, 0x0DDC, 0x0DCA },
	{ 0x0DDE, 0x0DD9, 0x0DDF },
	{ 0x0F43, 0x0F42, 0x0FB7 },
	{ 0x0F4D, 0x0F4C, 0x0FB7 },
	{ 0x0F52, 0x0F51, 0x0FB7 },
	{ 0x0F57, 0x0F56, 0x0FB7 },
	{ 0x0F5C, 0x0F5B, 0x0FB7 },
	{ 0x0F69, 0x0F40, 0x0FB5 },
	{ 0x0F73, 0x0F71, 0x0F72 },
	{ 0x0F75, 0x0F71, 0x0F74 },
	{ 0x0F76, 0x0FB2, 0x0F80 },
	{ 0x0F78, 0x0FB3, 0x0F80 },
	{ 0x0F81, 0x0F71, 0x0F80 },
	{ 0x0F93, 0x0F92, 0x0FB7 },
	{ 0x0F9D, 0x0F9C, 0x0FB7 },
	{ 0x0FA2, 0x0FA1, 0x0FB7 },
	{ 0x0FA7, 0x0FA6, 0x0FB7 },
	{ 0x0FAC, 0x0FAB, 0x0FB7 },
	{ 0x0FB9, 0x0F90, 0x0FB5 },
	{ 0x1026, 0x1025, 0x102E },
	{ 0x1E00, 0x0041, 0x0325 },
	{ 0x1E01, 0x0061, 0x0325 },
	{ 0x1E02, 0x0042, 0x0307 },
	{ 0x1E03, 0x0062, 0x0307 },
	{ 0x1E04, 0x0042, 0x0323 },
	{ 0x1E05, 0x0062, 0x0323 },
	{ 0x1E06, 0x0042, 0x0331 },
	{ 0x1E07, 0x0062, 0x0331 },
	{ 0x1E08, 0x00C7, 0x0301 },
	{ 0x1E09, 0x00E7, 0x0301 },
	{ 0x1E0A, 0x0044, 0x0307 },
	{ 0x1E0B, 0x0064, 0x0307 },
	{ 0x1E0C, 0x0044, 0x0323 },
	{ 0x1E0D, 0x0064, 0x0323 },
	{ 0x1E0E, 0x0044, 0x0331 },
	{ 0x1E0F, 0x0064, 0x0331 },
	{ 0x1E10, 0x0044, 0x0327 },
	{ 0x1E11, 0x0064, 0x0327 },
	{ 0x1E12, 0x0044, 0x032D },
	{ 0x1E13, 0x0064, 0x032D },
	{ 0x1E14, 0x0112, 0x0300 },
	{ 0x1E15, 0x0113, 0x0300 },
	{ 0x1E16, 0x0112, 0x0301 },
	{ 0x1E17, 0x0113, 0x0301 },
	{ 0x1E18, 0x0045, 0x032D },
	{ 0x1E19, 0x0065, 0x032D },
	{ 0x1E1A, 0x0045, 0x0330 },
	{ 0x1E1B, 0x0065, 0x0330 },
	{ 0x1E1C, 0x0228, 0x0306 },
	{ 0x1E1D, 0x0229, 0x0306 },
	{ 0x1E1E, 0x0046, 0x0307 },
	{ 0x1E1F, 0x0066, 0x0307 },
	{ 0x1E20, 0x0047, 0x0304 },
	{ 0x1E21, 0x0067, 0x0304 },
	{ 0x1E22, 0x0048, 0x0307 },
	{ 0x1E23, 0x0068, 0x0307 },
	{ 0x1E24, 0x0048, 0x0323 },
	{ 0x1E25, 0x0068, 0x0323 },
	{ 0x1E26, 0x0048, 0x0308 },
	{ 0x1E27, 0x0068, 0x0308 },
	{ 0x1E28, 0x0048, 0x0327 },
	{ 0x1E29, 0x0068, 0x0327 },
	{ 0x1E2A, 0x0048, 0x032E },
	{ 0x1E2B, 0x0068, 0x032E },
	{ 0x1E2C, 0x0049, 0x0330 },
	{ 0x1E2D, 0x0069, 0x0330 },
	{ 0x1E2E, 0x00CF, 0x0301 },
	{ 0x1E2F, 0x00EF, 0x0301 },
	{ 0x1E30, 0x004B, 0x0301 },
	{ 0x1E31, 0x006B, 0x0301 },
	{ 0x1E32, 0x004B, 0x0323 },
	{ 0x1E33, 0x006B, 0x0323 },
	{ 0x1E34, 0x004B, 0x0331 },
	{ 0x1E35, 0x006B, 0x0331 },
	{ 0x1E36, 0x004C, 0x0323 },
	{ 0x1E37, 0x006C, 0x0323 },
	{ 0x1E38, 0x1E36, 0x0304 },
	{ 0x1E39, 0x1E37, 0x0304 },
	{ 0x1E3A, 0x004C, 0x0331 },
	{ 0x1E3B, 0x006C, 0x0331 },
	{ 0x1E3C, 0x004C, 0x032D },
	{ 0x1E3D, 0x006C, 0x032D },
	{ 0x1E3E, 0x004D, 0x0301 },
	{ 0x1E3F, 0x006D, 0x0301 },
	{ 0x1E40, 0x004D, 0x0307 },
	{ 0x1E41, 0x006D, 0x0307 },
	{ 0x1E42, 0x004D, 0x0323 },
	{ 0x1E43, 0x006D, 0x0323 },
	{ 0x1E44, 0x004E, 0x0307 },
	{ 0x1E45, 0x006E, 0x0307 },
	{ 0x1E46, 0x004E, 0x0323 },
	{ 0x1E47, 0x006E, 0x0323 },
	{ 0x1E48, 0x004E, 0x0331 },
	{ 0x1E49, 0x006E, 0x0331 },
	{ 0x1E4A, 0x004E, 0x032D },
	{ 0x1E4B, 0x006E, 0x032D },
	{ 0x1E4C, 0x00D5, 0x0301 },
	{ 0x1E4D, 0x00F5, 0x0301 },
	{ 0x1E4E, 0x00D5, 0x0308 },
	{ 0x1E4F, 0x00F5, 0x0308 },
	{ 0x1E50, 0x014C, 0x0300 },
	{ 0x1E51, 0x014D, 0x0300 },
	{ 0x1E52, 0x014C, 0x0301 },
	{ 0x1E53, 0x014D, 0x0301 },
	{ 0x1E54, 0x0050, 0x0301 },
	{ 0x1E55, 0x0070, 0x0301 },
	{ 0x1E56, 0x0050, 0x0307 },
	{ 0x1E57, 0x0070, 0x0307 },
	{ 0x1E58, 0x0052, 0x0307 },
	{ 0x1E59, 0x0072, 0x0307 },
	{ 0x1E5A, 0x0052, 0x0323 },
	{ 0x1E5B, 0x0072, 0x0323 },
	{ 0x1E5C, 0x1E5A, 0x0304 },
	{ 0x1E5D, 0x1E5B, 0x0304 },
	{ 0x1E5E, 0x0052, 0x0331 },
	{ 0x1E5F, 0x0072, 0x0331 },
	{ 0x1E60, 0x0053, 0x0307 },
	{ 0x1E61, 0x0073, 0x0307 },
	{ 0x1E62, 0x0053, 0x0323 },
	{ 0x1E63, 0x0073, 0x0323 },
	{ 0x1E64, 0x015A, 0x0307 },
	{ 0x1E65, 0x015B, 0x0307 },
	{ 0x1E66, 0x0160, 0x0307 },
	{ 0x1E67, 0x0161, 0x0307 },
	{ 0x1E68, 0x1E62, 0x0307 },
	{ 0x1E69, 0x1E63, 0x0307 },
	{ 0x1E6A, 0x0054, 0x0307 },
	{ 0x1E6B, 0x0074, 0x0307 },
	{ 0x1E6C, 0x0054, 0x0323 },
	{ 0x1E6D, 0x0074, 0x0323 },
	{ 0x1E6E, 0x0054, 0x0331 },
	{ 0x1E6F, 0x0074, 0x0331 },
	{ 0x1E70, 0x0054, 0x032D },
	{ 0x1E71, 0x0074, 0x032D },
	{ 0x1E72, 0x0055, 0x0324 },
	{ 0x1E73, 0x0075, 0x0324 },
	{ 0x1E74, 0x0055, 0x0330 },
	{ 0x1E75, 0x0075, 0x0330 },
	{ 0x1E76, 0x0055, 0x032D },
	{ 0x1E77, 0x0075, 0x032D },
	{ 0x1E78, 0x0168, 0x0301 },
	{ 0x1E79, 0x0169, 0x0301 },
	{ 0x1E7A, 0x016A, 0x0308 },
	{ 0x1E7B, 0x016B, 0x0308 },
	{ 0x1E7C, 0x0056, 0x0303 },
	{ 0x1E7D, 0x0076, 0x0303 },
	{ 0x1E7E, 0x0056, 0x0323 },
	{ 0x1E7F, 0x0076, 0x0323 },
	{ 0x1E80, 0x0057, 0x0300 },
	{ 0x1E81, 0x0077, 0x0300 },
	{ 0x1E82, 0x0057, 0x0301 },
	{ 0x1E83, 0x0077, 0x0301 },
	{ 0x1E84, 0x0057, 0x0308 },
	{ 0x1E85, 0x0077, 0x0308 },
	{ 0x1E86, 0x0057, 0x0307 },
	{ 0x1E87, 0x0077, 0x0307 },
	{ 0x1E88, 0x0057, 0x0323 },
	{ 0x1E89, 0x0077, 0x0323 },
	{ 0x1E8A, 0x0058, 0x0307 },
	{ 0x1E8B, 0x0078, 0x0307 },
	{ 0x1E8C, 0x0058, 0x0308 },
	{ 0x1E8D, 0x0078, 0x0308 },
	{ 0x1E8E, 0x0059, 0x0307 },
	{ 0x1E8F, 0x0079, 0x0307 },
	{ 0x1E90, 0x005A, 0x0302 },
	{ 0x1E91, 0x007A, 0x0302 },
	{ 0x1E92, 0x005A, 0x0323 },
	{ 0x1E93, 0x007A, 0x0323 },
	{ 0x1E94, 0x005A, 0x0331 },
	{ 0x1E95, 0x007A, 0x0331 },
	{ 0x1E96, 0x0068, 0x0331 },
	{ 0x1E97, 0x0074, 0x0308 },
	{ 0x1E98, 0x0077, 0x030A },
	{ 0x1E99, 0x0079, 0x030A },
	{ 0x1E9B, 0x017F, 0x0307 },
	{ 0x1EA0, 0x0041, 0x0323 },
	{ 0x1EA1, 0x0061, 0x0323 },
	{ 0x1EA2, 0x0041, 0x0309 },
	{ 0x1EA3, 0x0061, 0x0309 },
	{ 0x1EA4, 0x00C2, 0x0301 },
	{ 0x1EA5, 0x00E2, 0x0301 },
	{ 0x1EA6, 0x00C2, 0x0300 },
	{ 0x1EA7, 0x00E2, 0x0300 },
	{ 0x1EA8, 0x00C2, 0x0309 },
	{ 0x1EA9, 0x00E2, 0x0309 },
	{ 0x1EAA, 0x00C2, 0x0303 },
	{ 0x1EAB, 0x00E2, 0x0303 },
	{ 0x1EAC, 0x1EA0, 0x0302 },
	{ 0x1EAD, 0x1EA1, 0x0302 },
	{ 0x1EAE, 0x0102, 0x0301 },
	{ 0x1EAF, 0x0103, 0x0301 },
	{ 0x1EB0, 0x0102, 0x0300 },
	{ 0x1EB1, 0x0103, 0x0300 },
	{ 0x1EB2, 0x0102, 0x0309 },
	{ 0x1EB3, 0x0103, 0x0309 },
	{ 0x1EB4, 0x0102, 0x0303 },
	{ 0x1EB5, 0x0103, 0x0303 },
	{ 0x1EB6, 0x1EA0, 0x0306 },
	{ 0x1EB7, 0x1EA1, 0x0306 },
	{ 0x1EB8, 0x0045, 0x0323 },
	{ 0x1EB9, 0x0065, 0x0323 },
	{ 0x1EBA, 0x0045, 0x0309 },
	{ 0x1EBB, 0x0065, 0x0309 },
	{ 0x1EBC, 0x0045, 0x0303 },
	{ 0x1EBD, 0x0065, 0x0303 },
	{ 0x1EBE, 0x00CA, 0x0301 },
	{ 0x1EBF, 0x00EA, 0x0301 },
	{ 0x1EC0, 0x00CA, 0x0300 },
	{ 0x1EC1, 0x00EA, 0x0300 },
	{ 0x1EC2, 0x00CA, 0x0309 },
	{ 0x1EC3, 0x00EA, 0x0309 },
	{ 0x1EC4, 0x00CA, 0x0303 },
	{ 0x1EC5, 0x00EA, 0x0303 },
	{ 0x1EC6, 0x1EB8, 0x0302 },
	{ 0x1EC7, 0x1EB9, 0x0302 },
	{ 0x1EC8, 0x0049, 0x0309 },
	{ 0x1EC9, 0x0069, 0x0309 },
	{ 0x1ECA, 0x0049, 0x0323 },
	{ 0x1ECB, 0x0069, 0x0323 },
	{ 0x1ECC, 0x004F, 0x0323 },
	{ 0x1ECD, 0x006F, 0x0323 },
	{ 0x1ECE, 0x004F, 0x0309 },
	{ 0x1ECF, 0x006F, 0x0309 },
	{ 0x1ED0, 0x00D4, 0x0301 },
	{ 0x1ED1, 0x00F4, 0x0301 },
	{ 0x1ED2, 0x00D4, 0x0300 },
	{ 0x1ED3, 0x00F4, 0x0300 },
	{ 0x1ED4, 0x00D4, 0x0309 },
	{ 0x1ED5, 0x00F4, 0x0309 },
	{ 0x1ED6, 0x00D4, 0x0303 },
	{ 0x1ED7, 0x00F4, 0x0303 },
	{ 0x1ED8, 0x1ECC, 0x0302 },
	{ 0x1ED9, 0x1ECD, 0x0302 },
	{ 0x1EDA, 0x01A0, 0x0301 },
	{ 0x1EDB, 0x01A1, 0x0301 },
	{ 0x1EDC, 0x01A0, 0x0300 },
	{ 0x1EDD, 0x01A1, 0x0300 },
	{ 0x1EDE, 0x01A0, 0x0309 },
	{ 0x1EDF, 0x01A1, 0x0309 },
	{ 0x1EE0, 0x01A0, 0x0303 },
	{ 0x1EE1, 0x01A1, 0x0303 },
	{ 0x1EE2, 0x01A0, 0x0323 },
	{ 0x1EE3, 0x01A1, 0x0323 },
	{ 0x1EE4, 0x0055, 0x0323 },
	{ 0x1EE5, 0x0075, 0x0323 },
	{ 0x1EE6, 0x0055, 0x0309 },
	{ 0x1EE7, 0x0075, 0x0309 },
	{ 0x1EE8, 0x01AF, 0x0301 },
	{ 0x1EE9, 0x01B0, 0x0301 },
	{ 0x1EEA, 0x01AF, 0x0300 },
	{ 0x1EEB, 0x01B0, 0x0300 },
	{ 0x1EEC, 0x01AF, 0x0309 },
	{ 0x1EED, 0x01B0, 0x0309 },
	{ 0x1EEE, 0x01AF, 0x0303 },
	{ 0x1EEF, 0x01B0, 0x0303 },
	{ 0x1EF0, 0x01AF, 0x0323 },
	{ 0x1EF1, 0x01B0, 0x0323 },
	{ 0x1EF2, 0x0059, 0x0300 },
	{ 0x1EF3, 0x0079, 0x0300 },
	{ 0x1EF4, 0x0059, 0x0323 },
	{ 0x1EF5, 0x0079, 0x0323 },
	{ 0x1EF6, 0x0059, 0x0309 },
	{ 0x1EF7, 0x0079, 0x0309 },
	{ 0x1EF8, 0x0059, 0x0303 },
	{ 0x1EF9, 0x0079, 0x0303 },
	{ 0x1F00, 0x03B1, 0x0313 },
	{ 0x1F01, 0x03B1, 0x0314 },
	{ 0x1F02, 0x1F00, 0x0300 },
	{ 0x1F03, 0x1F01, 0x0300 },
	{ 0x1F04, 0x1F00, 0x0301 },
	{ 0x1F05, 0x1F01, 0x0301 },
	{ 0x1F06, 0x1F00, 0x0342 },
	{ 0x1F07, 0x1F01, 0x0342 },
	{ 0x1F08, 0x0391, 0x0313 },
	{ 0x1F09, 0x0391, 0x0314 },
	{ 0x1F0A, 0x1F08, 0x0300 },
	{ 0x1F0B, 0x1F09, 0x0300 },
	{ 0x1F0C, 0x1F08, 0x0301 },
	{ 0x1F0D, 0x1F09, 0x0301 },
	{ 0x1F0E, 0x1F08, 0x0342 },
	{ 0x1F0F, 0x1F09, 0x0342 },
	{ 0x1F10, 0x03B5, 0x0313 },
	{ 0x1F11, 0x03B5, 0x0314 },
	{ 0x1F12, 0x1F10, 0x0300 },
	{ 0x1F13, 0x1F11, 0x0300 },
	{ 0x1F14, 0x1F10, 0x0301 },
	{ 0x1F15, 0x1F11, 0x0301 },
	{ 0x1F18, 0x0395, 0x0313 },
	{ 0x1F19, 0x0395, 0x0314 },
	{ 0x1F1A, 0x1F18, 0x0300 },
	{ 0x1F1B, 0x1F19, 0x0300 },
	{ 0x1F1C, 0x1F18, 0x0301 },
	{ 0x1F1D, 0x1F19, 0x0301 },
	{ 0x1F20, 0x03B7, 0x0313 },
	{ 0x1F21, 0x03B7, 0x0314 },
	{ 0x1F22, 0x1F20, 0x0300 },
	{ 0x1F23, 0x1F21, 0x0300 },
	{ 0x1F24, 0x1F20, 0x0301 },
	{ 0x1F25, 0x1F21, 0x0301 },
	{ 0x1F26, 0x1F20, 0x0342 },
	{ 0x1F27, 0x1F21, 0x0342 },
	{ 0x1F28, 0x0397, 0x0313 },
	{ 0x1F29, 0x0397, 0x0314 },
	{ 0x1F2A, 0x1F28, 0x0300 },
	{ 0x1F2B, 0x1F29, 0x0300 },
	{ 0x1F2C, 0x1F28, 0x0301 },
	{ 0x1F2D, 0x1F29, 0x0301 },
	{ 0x1F2E, 0x1F28, 0x0342 },
	{ 0x1F2F, 0x1F29, 0x0342 },
	{ 0x1F30, 0x03B9, 0x0313 },
	{ 0x1F31, 0x03B9, 0x0314 },
	{ 0x1F32, 0x1F30, 0x0300 },
	{ 0x1F33, 0x1F31, 0x0300 },
	{ 0x1F34, 0x1F30, 0x0301 },
	{ 0x1F35, 0x1F31, 0x0301 },
	{ 0x1F36, 0x1F30, 0x0342 },
	{ 0x1F37, 0x1F31, 0x0342 },
	{ 0x1F38, 0x0399, 0x0313 },
	{ 0x1F39, 0x0399, 0x0314 },
	{ 0x1F3A, 0x1F38, 0x0300 },
	{ 0x1F3B, 0x1F39, 0x0300 },
	{ 0x1F3C, 0x1F38, 0x0301 },
	{ 0x1F3D, 0x1F39, 0x0301 },
	{ 0x1F3E, 0x1F38, 0x0342 },
	{ 0x1F3F, 0x1F39, 0x0342 },
	{ 0x1F40, 0x03BF, 0x0313 },
	{ 0x1F41, 0x03BF, 0x0314 },
	{ 0x1F42, 0x1F40, 0x0300 },
	{ 0x1F43, 0x1F41, 0x0300 },
	{ 0x1F44, 0x1F40, 0x0301 },
	{ 0x1F45, 0x1F41, 0x0301 },
	{ 0x1F48, 0x039F, 0x0313 },
	{ 0x1F49, 0x039F, 0x0314 },
	{ 0x1F4A, 0x1F48, 0x0300 },
	{ 0x1F4B, 0x1F49, 0x0300 },
	{ 0x1F4C, 0x1F48, 0x0301 },
	{ 0x1F4D, 0x1F49, 0x0301 },
	{ 0x1F50, 0x03C5, 0x0313 },
	{ 0x1F51, 0x03C5, 0x0314 },
	{ 0x1F52, 0x1F50, 0x0300 },
	{ 0x1F53, 0x1F51, 0x0300 },
	{ 0x1F54, 0x1F50, 0x0301 },
	{ 0x1F55, 0x1F51, 0x0301 },
	{ 0x1F56, 0x1F50, 0x0342 },
	{ 0x1F57, 0x1F51, 0x0342 },
	{ 0x1F59, 0x03A5, 0x0314 },
	{ 0x1F5B, 0x1F59, 0x0300 },
	{ 0x1F5D, 0x1F59, 0x0301 },
	{ 0x1F5F, 0x1F59, 0x0342 },
	{ 0x1F60, 0x03C9, 0x0313 },
	{ 0x1F61, 0x03C9, 0x0314 },
	{ 0x1F62, 0x1F60, 0x0300 },
	{ 0x1F63, 0x1F61, 0x0300 },
	{ 0x1F64, 0x1F60, 0x0301 },
	{ 0x1F65, 0x1F61, 0x0301 },
	{ 0x1F66, 0x1F60, 0x0342 },
	{ 0x1F67, 0x1F61, 0x0342 },
	{ 0x1F68, 0x03A9, 0x0313 },
	{ 0x1F69, 0x03A9, 0x0314 },
	{ 0x1F6A, 0x1F68, 0x0300 },
	{ 0x1F6B, 0x1F69, 0x0300 },
	{ 0x1F6C, 0x1F68, 0x0301 },
	{ 0x1F6D, 0x1F69, 0x0301 },
	{ 0x1F6E, 0x1F68, 0x0342 },
	{ 0x1F6F, 0x1F69, 0x0342 },
	{ 0x1F70, 0x03B1, 0x0300 },
	{ 0x1F72, 0x03B5, 0x0300 },
	{ 0x1F74, 0x03B7, 0x0300 },
	{ 0x1F76, 0x03B9, 0x0300 },
	{ 0x1F78, 0x03BF, 0x0300 },
	{ 0x1F7A, 0x03C5, 0x0300 },
	{ 0x1F7C, 0x03C9, 0x0300 },
	{ 0x1F80, 0x1F00, 0x0345 },
	{ 0x1F81, 0x1F01, 0x0345 },
	{ 0x1F82, 0x1F02, 0x0345 },
	{ 0x1F83, 0x1F03, 0x0345 },
	{ 0x1F84, 0x1F04, 0x0345 },
	{ 0x1F85, 0x1F05, 0x0345 },
	{ 0x1F86, 0x1F06, 0x0345 },
	{ 0x1F87, 0x1F07, 0x0345 },
	{ 0x1F88, 0x1F08, 0x0345 },
	{ 0x1F89, 0x1F09, 0x0345 },
	{ 0x1F8A, 0x1F0A, 0x0345 },
	{ 0x1F8B, 0x1F0B, 0x0345 },
	{ 0x1F8C, 0x1F0C, 0x0345 },
	{ 0x1F8D, 0x1F0D, 0x0345 },
	{ 0x1F8E, 0x1F0E, 0x0345 },
	{ 0x1F8F, 0x1F0F, 0x0345 },
	{ 0x1F90, 0x1F20, 0x0345 },
	{ 0x1F91, 0x1F21, 0x0345 },
	{ 0x1F92, 0x1F22, 0x0345 },
	{ 0x1F93, 0x1F23, 0x0345 },
	{ 0x1F94, 0x1F24, 0x0345 },
	{ 0x1F95, 0x1F25, 0x0345 },
	{ 0x1F96, 0x1F26, 0x0345 },
	{ 0x1F97, 0x1F27, 0x0345 },
	{ 0x1F98, 0x1F28, 0x0345 },
	{ 0x1F99, 0x1F29, 0x0345 },
	{ 0x1F9A, 0x1F2A, 0x0345 },
	{ 0x1F9B, 0x1F2B, 0x0345 },
	{ 0x1F9C, 0x1F2C, 0x0345 },
	{ 0x1F9D, 0x1F2D, 0x0345 },
	{ 0x1F9E, 0x1F2E, 0x0345 },
	{ 0x1F9F, 0x1F2F, 0x0345 },
	{ 0x1FA0, 0x1F60, 0x0345 },
	{ 0x1FA1, 0x1F61, 0x0345 },
	{ 0x1FA2, 0x1F62, 0x0345 },
	{ 0x1FA3, 0x1F63, 0x0345 },
	{ 0x1FA4, 0x1F64, 0x0345 },
	{ 0x1FA5, 0x1F65, 0x0345 },
	{ 0x1FA6, 0x1F66, 0x0345 },
	{ 0x1FA7, 0x1F67, 0x0345 },
	{ 0x1FA8, 0x1F68, 0x0345 },
	{ 0x1FA9, 0x1F69, 0x0345 },
	{ 0x1FAA, 0x1F6A, 0x0345 },
	{ 0x1FAB, 0x1F6B, 0x0345 },
	{ 0x1FAC, 0x1F6C, 0x0345 },
	{ 0x1FAD, 0x1F6D, 0x0345 },
	{ 0x1FAE, 0x1F6E, 0x0345 },
	{ 0x1FAF, 0x1F6F, 0x0345 },
	{ 0x1FB0, 0x03B1, 0x0306 },
	{ 0x1FB1, 0x03B1, 0x0304 },
	{ 0x1FB2, 0x1F70, 0x0345 },
	{ 0x1FB3, 0x03B1, 0x0345 },
	{ 0x1FB4, 0x03AC, 0x0345 },
	{ 0x1FB6, 0x03B1, 0x0342 },
	{ 0x1FB7, 0x1FB6, 0x0345 },
	{ 0x1FB8, 0x0391, 0x0306 },
	{ 0x1FB9, 0x0391, 0x0304 },
	{ 0x1FBA, 0x0391, 0x0300 },
	{ 0x1FBC, 0x0391, 0x0345 },
	{ 0x1FC1, 0x00A8, 0x0342 },
	{ 0x1FC2, 0x1F74, 0x0345 },
	{ 0x1FC3, 0x03B7, 0x0345 },
	{ 0x1FC4, 0x03AE, 0x0345 },
	{ 0x1FC6, 0x03B7, 0x0342 },
	{ 0x1FC7, 0x1FC6, 0x0345 },
	{ 0x1FC8, 0x0395, 0x0300 },
	{ 0x1FCA, 0x0397, 0x0300 },
	{ 0x1FCC, 0x0397, 0x0345 },
	{ 0x1FCD, 0x1FBF, 0x0300 },
	{ 0x1FCE, 0x1FBF, 0x0301 },
	{ 0x1FCF, 0x1FBF, 0x0342 },
	{ 0x1FD0, 0x03B9, 0x0306 },
	{ 0x1FD1, 0x03B9, 0x0304 },
	{ 0x1FD2, 0x03CA, 0x0300 },
	{ 0x1FD6, 0x03B9, 0x0342 },
	{ 0x1FD7, 0x03CA, 0x0342 },
	{ 0x1FD8, 0x0399, 0x0306 },
	{ 0x1FD9, 0x0399, 0x0304 },
	{ 0x1FDA, 0x0399, 0x0300 },
	{ 0x1FDD, 0x1FFE, 0x0300 },
	{ 0x1FDE, 0x1FFE, 0x0301 },
	{ 0x1FDF, 0x1FFE, 0x0342 },
	{ 0x1FE0, 0x03C5, 0x0306 },
	{ 0x1FE1, 0x03C5, 0x0304 },
	{ 0x1FE2, 0x03CB, 0x0300 },
	{ 0x1FE4, 0x03C1, 0x0313 },
	{ 0x1FE5, 0x03C1, 0x0314 },
	{ 0x1FE6, 0x03C5, 0x0342 },
	{ 0x1FE7, 0x03CB, 0x0342 },
	{ 0x1FE8, 0x03A5, 0x0306 },
	{ 0x1FE9, 0x03A5, 0x0304 },
	{ 0x1FEA, 0x03A5, 0x0300 },
	{ 0x1FEC, 0x03A1, 0x0314 },
	{ 0x1FED, 0x00A8, 0x0300 },
	{ 0x1FF2, 0x1F7C, 0x0345 },
	{ 0x1FF3, 0x03C9, 0x0345 },
	{ 0x1FF4, 0x03CE, 0x0345 },
	{ 0x1FF6, 0x03C9, 0x0342 },
	{ 0x1FF7, 0x1FF6, 0x0345 },
	{ 0x1FF8, 0x039F, 0x0300 },
	{ 0x1FFA, 0x03A9, 0x0300 },
	{ 0x1FFC, 0x03A9, 0x0345 },
	{ 0x219A, 0x2190, 0x0338 },
	{ 0x219B, 0x2192, 0x0338 },
	{ 0x21AE, 0x2194, 0x0338 },
	{ 0x21CD, 0x21D0, 0x0338 },
	{ 0x21CE, 0x21D4, 0x0338 },
	{ 0x21CF, 0x21D2, 0x0338 },
	{ 0x2204, 0x2203, 0x0338 },
	{ 0x2209, 0x2208, 0x0338 },
	{ 0x220C, 0x220B, 0x0338 },
	{ 0x2224, 0x2223, 0x0338 },
	{ 0x2226, 0x2225, 0x0338 },
	{ 0x2241, 0x223C, 0x0338 },
	{ 0x2244, 0x2243, 0x0338 },
	{ 0x2247, 0x2245, 0x0338 },
	{ 0x2249, 0x2248, 0x0338 },
	{ 0x2260, 0x003D, 0x0338 },
	{ 0x2262, 0x2261, 0x0338 },
	{ 0x226D, 0x224D, 0x0338 },
	{ 0x226E, 0x003C, 0x0338 },
	{ 0x226F, 0x003E, 0x0338 },
	{ 0x2270, 0x2264, 0x0338 },
	{ 0x2271, 0x2265, 0x0338 },
	{ 0x2274, 0x2272, 0x0338 },
	{ 0x2275, 0x2273, 0x0338 },
	{ 0x2278, 0x2276, 0x0338 },
	{ 0x2279, 0x2277, 0x0338 },
	{ 0x2280, 0x227A, 0x0338 },
	{ 0x2281, 0x227B, 0x0338 },
	{ 0x2284, 0x2282, 0x0338 },
	{ 0x2285, 0x2283, 0x0338 },
	{ 0x2288, 0x2286, 0x0338 },
	{ 0x2289, 0x2287, 0x0338 },
	{ 0x22AC, 0x22A2, 0x0338 },
	{ 0x22AD, 0x22A8, 0x0338 },
	{ 0x22AE, 0x22A9, 0x0338 },
	{ 0x22AF, 0x22AB, 0x0338 },
	{ 0x22E0, 0x227C, 0x0338 },
	{ 0x22E1, 0x227D, 0x0338 },
	{ 0x22E2, 0x2291, 0x0338 },
	{ 0x22E3, 0x2292, 0x0338 },
	{ 0x22EA, 0x22B2, 0x0338 },
	{ 0x22EB, 0x22B3, 0x0338 },
	{ 0x22EC, 0x22B4, 0x0338 },
	{ 0x22ED, 0x22B5, 0x0338 },
	{ 0x2ADC, 0x2ADD, 0x0338 },
	{ 0x304C, 0x304B, 0x3099 },
	{ 0x304E, 0x304D, 0x3099 },
	{ 0x3050, 0x304F, 0x3099 },
	{ 0x3052, 0x3051, 0x3099 },
	{ 0x3054, 0x3053, 0x3099 },
	{ 0x3056, 0x3055, 0x3099 },
	{ 0x3058, 0x3057, 0x3099 },
	{ 0x305A, 0x3059, 0x3099 },
	{ 0x305C, 0x305B, 0x3099 },
	{ 0x305E, 0x305D, 0x3099 },
	{ 0x3060, 0x305F, 0x3099 },
	{ 0x3062, 0x3061, 0x3099 },
	{ 0x3065, 0x3064, 0x3099 },
	{ 0x3067, 0x3066, 0x3099 },
	{ 0x3069, 0x3068, 0x3099 },
	{ 0x3070, 0x306F, 0x3099 },
	{ 0x3071, 0x306F, 0x309A },
	{ 0x3073, 0x3072, 0x3099 },
	{ 0x3074, 0x3072, 0x309A },
	{ 0x3076, 0x3075, 0x3099 },
	{ 0x3077, 0x3075, 0x309A },
	{ 0x3079, 0x3078, 0x3099 },
	{ 0x307A, 0x3078, 0x309A },
	{ 0x307C, 0x307B, 0x3099 },
	{ 0x307D, 0x307B, 0x309A },
	{ 0x3094, 0x3046, 0x3099 },
	{ 0x309E, 0x309D, 0x3099 },
	{ 0x30AC, 0x30AB, 0x3099 },
	{ 0x30AE, 0x30AD, 0x3099 },
	{ 0x30B0, 0x30AF, 0x3099 },
	{ 0x30B2, 0x30B1, 0x3099 },
	{ 0x30B4, 0x30B3, 0x3099 },
	{ 0x30B6, 0x30B5, 0x3099 },
	{ 0x30B8, 0x30B7, 0x3099 },
	{ 0x30BA, 0x30B9, 0x3099 },
	{ 0x30BC, 0x30BB, 0x3099 },
	{ 0x30BE, 0x30BD, 0x3099 },
	{ 0x30C0, 0x30BF, 0x3099 },
	{ 0x30C2, 0x30C1, 0x3099 },
	{ 0x30C5, 0x30C4, 0x3099 },
	{ 0x30C7, 0x30C6, 0x3099 },
	{ 0x30C9, 0x30C8, 0x3099 },
	{ 0x30D0, 0x30CF, 0x3099 },
	{ 0x30D1, 0x30CF, 0x309A },
	{ 0x30D3, 0x30D2, 0x3099 },
	{ 0x30D4, 0x30D2, 0x309A },
	{ 0x30D6, 0x30D5, 0x3099 },
	{ 0x30D7, 0x30D5, 0x309A },
	{ 0x30D9, 0x30D8, 0x3099 },
	{ 0x30DA, 0x30D8, 0x309A },
	{ 0x30DC, 0x30DB, 0x3099 },
	{ 0x30DD, 0x30DB, 0x309A },
	{ 0x30F4, 0x30A6, 0x3099 },
	{ 0x30F7, 0x30EF, 0x3099 },
	{ 0x30F8, 0x30F0, 0x3099 },
	{ 0x30F9, 0x30F1, 0x3099 },
	{ 0x30FA, 0x30F2, 0x3099 },
	{ 0x30FE, 0x30FD, 0x3099 },
	{ 0xFB1D, 0x05D9, 0x05B4 },
	{ 0xFB1F, 0x05F2, 0x05B7 },
	{ 0xFB2A, 0x05E9, 0x05C1 },
	{ 0xFB2B, 0x05E9, 0x05C2 },
	{ 0xFB2C, 0xFB49, 0x05C1 },
	{ 0xFB2D, 0xFB49, 0x05C2 },
	{ 0xFB2E, 0x05D0, 0x05B7 },
	{ 0xFB2F, 0x05D0, 0x05B8 },
	{ 0xFB30, 0x05D0, 0x05BC },
	{ 0xFB31, 0x05D1, 0x05BC },
	{ 0xFB32, 0x05D2, 0x05BC },
	{ 0xFB33, 0x05D3, 0x05BC },
	{ 0xFB34, 0x05D4, 0x05BC },
	{ 0xFB35, 0x05D5, 0x05BC },
	{ 0xFB36, 0x05D6, 0x05BC },
	{ 0xFB38, 0x05D8, 0x05BC },
	{ 0xFB39, 0x05D9, 0x05BC },
	{ 0xFB3A, 0x05DA, 0x05BC },
	{ 0xFB3B, 0x05DB, 0x05BC },
	{ 0xFB3C, 0x05DC, 0x05BC },
	{ 0xFB3E, 0x05DE, 0x05BC },
	{ 0xFB40, 0x05E0, 0x05BC },
	{ 0xFB41, 0x05E1, 0x05BC },
	{ 0xFB43, 0x05E3, 0x05BC },
	{ 0xFB44, 0x05E4, 0x05BC },
	{ 0xFB46, 0x05E6, 0x05BC },
	{ 0xFB47, 0x05E7, 0x05BC },
	{ 0xFB48, 0x05E8, 0x05BC },
	{ 0xFB49, 0x05E9, 0x05BC },
	{ 0xFB4A, 0x05EA, 0x05BC },
	{ 0xFB4B, 0x05D5, 0x05B9 },
	{ 0xFB4C, 0x05D1, 0x05BF },
	{ 0xFB4D, 0x05DB, 0x05BF },
	{ 0xFB4E, 0x05E4, 0x05BF },
	/* out of range of unsigned short... */
#if 0
	{ 0x1D15E, 0x1D157, 0x1D165 },
	{ 0x1D15F, 0x1D158, 0x1D165 },
	{ 0x1D160, 0x1D15F, 0x1D16E },
	{ 0x1D161, 0x1D15F, 0x1D16F },
	{ 0x1D162, 0x1D15F, 0x1D170 },
	{ 0x1D163, 0x1D15F, 0x1D171 },
	{ 0x1D164, 0x1D15F, 0x1D172 },
	{ 0x1D1BB, 0x1D1B9, 0x1D165 },
	{ 0x1D1BC, 0x1D1BA, 0x1D165 },
	{ 0x1D1BD, 0x1D1BB, 0x1D16E },
	{ 0x1D1BE, 0x1D1BC, 0x1D16E },
	{ 0x1D1BF, 0x1D1BB, 0x1D16F },
	{ 0x1D1C0, 0x1D1BC, 0x1D16F },
#endif
	/* special hack, treat Arabic ligatures as combining characters */
	/* combine them to the isolated presentation form, then let
	 * the shaping and joining take care of it */
	{ 0xFEF5, 0x0644, 0x0622 }, /* LAM_ALEF_MADDA */
	{ 0xFEF7, 0x0644, 0x0623 }, /* LAM_ALEF_HAMZA_ABOVE */
	{ 0xFEF9, 0x0644, 0x0625 }, /* LAM_ALEF_HAMZA_BELOW */
	{ 0xFEFB, 0x0644, 0x0627 }, /* LAM_ALEF */
};

/* -------------------------- local functions ------------------------------ */


/* look-up functions, maybe theese should use binary search?
   would require a duplicate of comb_table to reverse map... */
static int
get_combining_class(unsigned short ch)
{
	int count;
	int table_size = sizeof(combclass_table) / sizeof(combclass_table[0]);

	for (count = 0; count < table_size; count++)
	{
		if (combclass_table[count].key == ch)
		{
			return combclass_table[count].combclass;
		}
	}

	return 0;
}

static const char_comb_t*
get_comb_entry_decomposed(unsigned short ch)
{
	int count;
	int table_size = sizeof(comb_table) / sizeof(comb_table[0]);

	for (count = 0; count < table_size; count++)
	{
		if (comb_table[count].key == ch)
		{
			return &comb_table[count];
		}
	}

	return NULL;
}

static unsigned short
get_comb_entry_composed(unsigned short first, unsigned short second)
{
	int count;
	int table_size = sizeof(comb_table) / sizeof(comb_table[0]);

	for (count = 0; count < table_size; count++)
	{
		if (comb_table[count].first == first &&
		    comb_table[count].second == second)
		{
			return comb_table[count].key;
		}
	}

	return (unsigned short) 0;
}

static int
convert_to_ucs2(
	const unsigned char *str_utf8, unsigned short *str_ucs2, int len)
{
	int in_pos = 0;
	int out_pos = 0;
	while (in_pos < len)
	{
		if (str_utf8[in_pos] <= 0x7f)
		{
			str_ucs2[out_pos] =
				(unsigned short)str_utf8[in_pos];
			in_pos++;
		}
		else
		{
			if ((str_utf8[in_pos] & 0300) != 0300)
			{
				/* out of sync */
				str_ucs2[out_pos] = REPLACEMENT_CHARACTER;
				in_pos++;
			}
			else if (in_pos < len-1 && str_utf8[in_pos] <= 0xdf &&
				 str_utf8[in_pos + 1] <= 0xbf &&
				 str_utf8[in_pos + 1] >= 0x80)
			{
				str_ucs2[out_pos] =
					((str_utf8[in_pos] & 0x1f) << 6) +
					(str_utf8[in_pos+1] & 0x3f);
				/* check for overlong sequence */
				if(str_ucs2[out_pos] < 0x80)
					str_ucs2[out_pos] =
						REPLACEMENT_CHARACTER;
				in_pos += 2;
			}
			else if (in_pos < len-2 && str_utf8[in_pos] <= 0xef &&
				 str_utf8[in_pos + 1] <= 0xbf &&
				 str_utf8[in_pos + 1] >= 0x80 &&
				 str_utf8[in_pos + 2] <= 0xbf &&
				 str_utf8[in_pos + 2] >= 0x80)
			{
				str_ucs2[out_pos] =
					((str_utf8[in_pos] & 0x0f) << 12) +
					((str_utf8[in_pos+1] & 0x3f) << 6) +
					(str_utf8[in_pos+2] & 0x3f);
				/* check for overlong sequence */
				if(str_ucs2[out_pos] < 0x800)
					str_ucs2[out_pos] =
						REPLACEMENT_CHARACTER;
				in_pos += 3;
			}
			else
			{
				/* incomplete sequence */
				str_ucs2[out_pos] = REPLACEMENT_CHARACTER;
				in_pos++;
			}
		}
		out_pos++;
	}
	return out_pos;
}

static int
convert_to_utf8(
	const unsigned short *str_ucs2, unsigned char *str_utf8, int len)
{
	int in_pos = 0;
	int out_pos = 0;

	for (in_pos = 0 ; in_pos < len ; in_pos++)
	{
		if (str_ucs2[in_pos] <= 0x7f)
		{
			str_utf8[out_pos] = str_ucs2[in_pos];
			out_pos++;
		}
		else if (str_ucs2[in_pos] <= 0x7ff)
		{
			str_utf8[out_pos] =
				(str_ucs2[in_pos] >> 6) | 0xc0;
			str_utf8[out_pos+1] =
				(str_ucs2[in_pos] & 0x3f) | 0x80;
			out_pos += 2;
		}
		else
		{
			str_utf8[out_pos] =
				(str_ucs2[in_pos] >> 12) | 0xe0;
			str_utf8[out_pos+1] =
				((str_ucs2[in_pos] & 0xfff) >> 6) | 0x80;
			str_utf8[out_pos+2] =
				(str_ucs2[in_pos] & 0x3f) | 0x80;
			out_pos += 3;
		}
		/* this doesn't handle values outside UCS2 (16-bit) */
	}
	return out_pos;
}


/* main procedure:
   takes a pointer to a string (UTF-8)
   first decomposes string, then rearrange combining characters, the
   combines them back.
   Result is stored in original string (can never be "expanded" from
   original size), new length is returned
*/


int
CombineChars(
	unsigned char *str_visual, int len, superimpose_char_t **comb_chars,
	int **l_to_v)
{
	int i,j,k;  /* counters */
	unsigned short *source;
	unsigned short *dest;
	int *source_v_to_l;
	int *dest_v_to_l;
	int str_len;
	int in_str_len;
	int out_str_len;
	int comp_str_len = 0;
  	Bool has_changed;

	/* if input has zero length, return immediatly */
	if (len == 0)
	{
		return 0;
	}

	/* decompose composed characters */
	source = (unsigned short *)safemalloc(
		(len + 1) * sizeof(unsigned short));
	/* convert from UTF-8-encoded text to internal 16-bit encoding */
	str_len = convert_to_ucs2(str_visual,source,len);
	in_str_len = str_len;
	/* we don't really need to NULL-terminate source, since we
	   have string length */

	/* be pessimistic, assume all characters are decomposed */
	dest = (unsigned short *)safemalloc(
		(str_len + 1) * 2 * sizeof(unsigned short));
	/* use theese to keep track of the mapping of characters from
	   logical to visual */
	source_v_to_l = (int *)safemalloc(str_len * sizeof(int));
	dest_v_to_l = (int *)safemalloc(str_len * 2 * sizeof(int));
	/* setup initial mapping 1-to-1 */
	for(i = 0 ; i < str_len ; i++)
	{
		source_v_to_l[i] = i;
	}
	do
	{
		has_changed = False;
		for (i = 0, j = 0; i < str_len; i++)
		{
			const char_comb_t *decomp =
				get_comb_entry_decomposed(source[i]);
			/* current character is decomposable */
			if (decomp)
			{
				dest[j] = decomp->first;
				dest[j+1] = decomp->second;
				dest_v_to_l[j] = source_v_to_l[i];
				dest_v_to_l[j+1] = source_v_to_l[i];
				j += 2;
				has_changed = True;
			}
			else /* leave it as is */
			{
				dest[j] = source[i];
				dest_v_to_l[j] = source_v_to_l[i];
				j++;
			}
		}

		/* now swap */
		free(source);
		free(source_v_to_l);
		source = dest;
		source_v_to_l = dest_v_to_l;
		str_len = j;
		dest = (unsigned short *)safemalloc(
			(str_len + 1) * 2 * sizeof(unsigned short));
		dest_v_to_l = (int *)safemalloc(str_len * 2 * sizeof(int));
	} while (has_changed);
	/* source now holds decomposed string (got swapped before exiting
	   loop, str_len holds string length */
	/* we reuse dest for composing, can use existing string lengths
	   since it will only get shorter */
	/* source_v_to_l holds the mapping from positions in decomposed
	   string to original string */

	/* rearrange combining characters */
	do
	{
		has_changed = False;
		for (i = 0; i < str_len - 1; i++)
		{
			/* swap if combining-class(c1) > combining-class(c2)
			   and combining-class(c2) != 0 */
			/* use negative values for marks that have combining
			   class 0, but should be taken out for drawing
			   superimposed */
			int c1 = get_combining_class(source[i]);
			int c2 = get_combining_class(source[i+1]);
			if (c1 > c2 && c2 > 0)
			{
				unsigned short temp = source[i];
				int temp_v_to_l = source_v_to_l[i];
				source[i] = source[i+1];
				source[i+1] = temp;
				source_v_to_l[i] = source_v_to_l[i+1];
				source_v_to_l[i+1] = temp_v_to_l;
				has_changed = True;
			}
		}
	} while (has_changed);

	/* compose */
	do
	{
		unsigned short *temp;
		int *temp_v_to_l;
		Bool last_changed = False;
		has_changed = False;

		for (i = 0, j = 0; i < str_len - 1; j++)
		{
			unsigned short composed =
				get_comb_entry_composed(source[i],
							source[i+1]);
			dest_v_to_l[j] = source_v_to_l[i];
			if (composed != 0)
			{
				dest[j] = composed;
				/* if the last character was "absorbed" */
				if (i == str_len - 2)
				{
					last_changed = True;
				}
				i += 2;
				has_changed = True;
			}
			else
			{
				dest[j] = source[i];
				i++;
			}
		}
		temp = dest;
		dest = source;
		source = temp;
		temp_v_to_l = dest_v_to_l;
		dest_v_to_l = source_v_to_l;
		source_v_to_l = temp_v_to_l;
		/* fixup the last character, the loop above goes to second
		   last, since it needs to look at 2 consecutive,
		   if the last character is a non-combining character */
		/* since we have an immediate return on zero length, this works
		   otherwise this would introduce crap here */
		if (!last_changed)
		{
			source[j] = dest[i];
			source_v_to_l[j] = dest_v_to_l[i];
			str_len = j+1;
		}
		else
		{
			str_len = j;
		}
	} while (has_changed);

	/* source contains composed string */

	/* gather "uncomposed" combining characters here for rendering
	  over normal characters later */
	comp_str_len = 0;
	if (comb_chars != NULL)
	{
		/* calculate number of combining characters left */
		for (i = 0 ; i < str_len ; i++)
		{
			if (get_combining_class(source[i]) != 0)
			{
				comp_str_len++;
			}
		}
		/* allocate storage for combining characters */
		*comb_chars = (superimpose_char_t *)
			safemalloc((comp_str_len + 1) *
				   sizeof(superimpose_char_t));
	}
	for (i = 0,j = 0,k = 0 ; i < str_len ; i++)
	{
		/* if character is non-combining,
		   just copy it over to output */
		/* if first character is a combing character, just output
		   it as if it where a base character */
		if (get_combining_class(source[i]) == 0)
		{
			dest[j] = source[i];
			dest_v_to_l[j] = source_v_to_l[i];
			j++;
		}
		else
		{
			if (comb_chars != NULL)
			{
				/* store composing character as associated
				   with last base charcter */
				(*comb_chars)[k].position = j == 0 ? 0 : j-1;
				(*comb_chars)[k].c.byte1 = source[i] >> 8;
				(*comb_chars)[k].c.byte2 = source[i] & 0xff;
				k++;
			}
		}
	}
	/* terminate */
	if (comb_chars != NULL)
	{
		(*comb_chars)[comp_str_len].position = 0;
		(*comb_chars)[comp_str_len].c.byte1 = 0;
		(*comb_chars)[comp_str_len].c.byte2 = 0;
	}
	str_len = convert_to_utf8(dest,str_visual,j);
	out_str_len = j;
	str_visual[str_len] = 0;

	if(l_to_v != NULL)
	{
		*l_to_v = (int *)safemalloc((in_str_len + 1) * sizeof(int));
		/* map the visual to logical mapping obtained above into
		   a logical to visual mapping */
		/* setup the final mapping from logical to visual positions */
		/* if no base characters out, all positions map to zero,
		   because there we have combining chars in that case */
		if(out_str_len == 0)
		{
			for(i = 0 ; i < in_str_len ; i++)
			{
				(*l_to_v)[i] = 0;
			}
		}
		for(i = 0, j = 0 ; i < out_str_len ; i++)
		{
			/* for each element in mapping from visual string
			   insert "backtracked" references from logical
			   string by inserting consequitive entries, as many
			   as the step in the mapping from visual to logical
			*/
			int step = (i == out_str_len - 1) ?
				    in_str_len - j :
				    dest_v_to_l[i+1] - dest_v_to_l[i];
			for(k = 0 ; k < step ; k++, j++)
			{
				(*l_to_v)[j] = i;
			}
		}
		/* terminated it with -1, to avoid have to send around
		   lenghts */
		(*l_to_v)[in_str_len] = -1;
	}

	/* clean up */
	free(source);
	free(dest);
	free(source_v_to_l);
	free(dest_v_to_l);

	return str_len;
}
